from rest_framework import viewsets
from .serializers import UserSerializers
from .models import User
from user.views import auth
from django.contrib.auth.hashers import make_password
from django.http import JsonResponse
from rest_framework.pagination import PageNumberPagination
from django.db.models import Q
from rest_framework.authentication import SessionAuthentication

# 分页类
class MyPageNumberPagination(PageNumberPagination):
    # 设置url中的取多少页的key
    page_query_param = 'page'
    # 设置url中设置取数据条数的key
    page_size_query_param = 'size'
    # 设置每一页的数据条数
    page_size = 10
    # 设置每一页最多可取的数据数
    max_page_size = 100

# 取消csrf验证
class CsrfExemptSessionAuthentication(SessionAuthentication):
    def enforce_csrf(self, request):
        return


class UserViewSet(viewsets.ModelViewSet):
    serializer_class = UserSerializers
    queryset = User.objects.all()
    pagination_class = MyPageNumberPagination  # 指定该视图类的分页器
    authentication_classes = (CsrfExemptSessionAuthentication,)

    # 用户列表
    @auth(True)
    def list(self, request):
        res = super().list(request)
        data = res.data
        res.data = {
            'code': '200',
            'msg': '响应成功!',
            'data': data
        }
        return res

    # 注册使用自定义的接口
    def create(self, request):
        pass

    # 获取/查看某一个用户
    @auth(True)
    def retrieve(self, request, pk=None):
        tmp_user = User.get_by_pk(pk)
        data = {k: getattr(tmp_user, k)
                for k in self.serializer_class.Meta.fields}
        res = {
            'code': '200',
            'msg': '响应成功!',
            'data': data
        }
        return JsonResponse(res)

    # 更新用户
    @auth(True)
    def update(self, request, pk=None):
        # 可更新的字段
        fields = self.serializer_class.Meta.fields

        user = User.get_by_pk(pk)

        # 如果更新用户名，需要检测用户名的有效性以及是否已存在
        if username := request.data.get('username'):
            # 检测用户名的合法性
            if not User.is_valid_username(username):
                return JsonResponse(
                    {
                        'code': '400',
                        'msg': '更新失败，用户名只能由数字，字母，下划线以及中文组成，且长度不能超过10!'
                    }
                )
            # 判断用户名是否已存在
            if User.objects.filter(Q(username=username) & ~Q(id=user.id)).exists():
                return JsonResponse(
                    {
                        'code': '400',
                        'msg': '更新失败，该用户名已存在！'
                    }
                )

        # 返回的数据
        data = {}
        # 若更新密码，需要额外加密
        if password := request.data.get('password'):
            user.password = make_password(password)
            data['password'] = password

        for field in fields:
            setattr(user, field, request.data.get(field, getattr(user, field)))
        user.save()

        data.update(
            {field: getattr(user, field) for field in fields}
        )
        return JsonResponse({'code': '200', 'msg': '更新成功!', 'data': data})

    # 删除用户
    @auth(True)
    def destroy(self, request, pk=None):
        tmp_user = User.get_by_pk(pk)
        if not tmp_user:
            return JsonResponse({
                'code': '400',
                'msg': '删除失败,未找到相关用户!'
            })
        tmp_user.delete()

        return JsonResponse({
            'code': '200',
            'msg': '删除成功!'
        })
